package com.mud.dnd.ejb.services;

import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

import javax.ejb.EJB;
import javax.ejb.LocalBean;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionManagement;


import com.mud.dnd.domain.common.DAOException;
import com.mud.dnd.domain.dao.DnDDAO;
import com.mud.dnd.domain.model.Session;
import com.mud.dnd.domain.model.User;
import com.mud.dnd.domain.model.User.Role;
import com.mud.dnd.ejb.common.AuthenticationException;

/**
 * Session Bean implementation class UserManager
 */
@Stateless
@TransactionManagement
public class AuthenticationServiceImpl implements AuthenticationService {

	@EJB
	private DnDDAO dao;
	
	
    /**
     * Default constructor. 
     */
    public AuthenticationServiceImpl() {
       
    }
    
  
    @Override
    @TransactionAttribute
	public String loginUser(String name, String password) throws DAOException, AuthenticationException
    {
    	User user = dao.getUserData(name);
    	if(!user.getPassword().equals(createHash(password)))
    	{
    		throw new AuthenticationException("Authentication error.");
    	}
    	String sessionID = createHash((UUID.randomUUID().toString()));
    	
    	Date expDate = new Date();
    	expDate = createExpDate(expDate, 30);
    	
    	dao.updateUserSession(user, sessionID, expDate);
    			
    	return sessionID;
    }
    
    
    @Override
    @TransactionAttribute
	public boolean checkSessionForUser(String name, String sessionID) throws DAOException
    {
    	if(name== null || sessionID==null)
    	{
    		return false;
    	}
    	
    	
    	//*******************************************************************************
    	//FIXME ezt itt nem szavad itthagyni
    	if(name.equals("kornal") && sessionID.equals("csinaldmegalogint"))
    	{
    		return true;
    	}
    	//*******************************************************************************
    	
    	User user = dao.getUserData(name);
    	
    	List<Session> sessionList = dao.getSessionParametersforUser(user);
    	Date curDate = new Date();
    	boolean isActiveSession = false;
    	for(Session s : sessionList)
    	{
    		if(s.getSessionExp().after(curDate) && s.getSessionID().equals(sessionID))
    		{
    			isActiveSession = true;
    			break;
    		}
    		
    	}
    	//FIXME visszacsinálni
    	/*if(isActiveSession)
    	{
    	
        	Date expDate = createExpDate(curDate, 30);
        	dao.updateUserSession(user, sessionID, expDate);
    		
    	}*/
    	
    	
    	return isActiveSession;
    }
    
   
    @Override
    @TransactionAttribute
	public int createUser(String name, String password, Role role) throws DAOException, AuthenticationException
    {
    	
    	
    	return dao.createUser(name, createHash(password), role);
    }
    
 
    
    @Override
    @TransactionAttribute
    public User getUserData(String name) throws DAOException
    {
    	return dao.getUserData(name);
    	
    }
    
    
  
    
    @Override
    @TransactionAttribute
    public void deleteUser(User user) throws DAOException
    {
    	dao.deleteUser(user.getId());
    	
    }
    
    @Override
    @TransactionAttribute
    public void clearSessionforUser(User user) throws DAOException
    {
    	dao.clearSessionforUser(user);
    }
    
    @Override
    @TransactionAttribute
    public void clearExpiredSessions()
    {
    	Date now = new Date();
    	
    	dao.deleteSessionsExpsBefore(now);
    }
    
    @Override
    @TransactionAttribute
    public boolean checkIfUserIsOwner(String userName,int GameItemID) throws DAOException
    {
    	int ownerID = dao.getDnDItemOwnerID(GameItemID);
    	User subject = dao.getUserData(userName);
    	if(subject.getId()==ownerID || subject.getRole()==Role.Admin)
    	{
    		return true;
    	}
    	else
    	{
    		return false;
    	}
    	
    }
   
    
    
    private String createHash(String value) throws AuthenticationException
    {
    	
    	String md5 = null;
        
		try {
			MessageDigest digest = MessageDigest.getInstance("MD5");
			digest.update(value.getBytes(), 0, value.length());
			md5 = new BigInteger(1, digest.digest()).toString(16);
		} catch (NoSuchAlgorithmException e) {

			throw new AuthenticationException("Authentication error.");
		}
		return md5;
    }
    
    private Date createExpDate(Date curDate, int timeout)
    {
    
    	Calendar cal = Calendar.getInstance();
    	cal.setTime(curDate);
    	cal.add(Calendar.MINUTE, timeout);
    	Date expDate=cal.getTime();
    	return expDate;
    }
    
   
    
    
    
 
    
    

}
